<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Sales\Controller;

use Admin\Controller\AdminActionController;
use Admin\Data\Common;
use Admin\Entity\Delivery;
use Admin\Service\Common\ExpressApi;
use Doctrine\ORM\EntityManager;
use Goods\Entity\GoodsVirtual;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\ViewModel;
use Operation\Service\UserCouponManager;
use Sales\Entity\Order;
use Sales\Entity\OrderChangeAmount;
use Sales\Entity\OrderDeliveryAddress;
use Sales\Entity\OrderDiscountRecord;
use Sales\Entity\OrderGoods;
use Sales\Entity\OrderSelfLocation;
use Sales\Entity\OrderStatus;
use Sales\Form\CancelOrderForm;
use Sales\Form\ChangeOrderAmountForm;
use Sales\Form\EditOneOrderExpressNumberForm;
use Sales\Form\EditOrderExpressNumberForm;
use Sales\Form\PayOrderForm;
use Sales\Form\ReceiptOrderForm;
use Sales\Form\SearchOrderForm;
use Sales\Form\SearchOrderPaymentLogForm;
use Sales\Form\SendOrderGoodsVirtualForm;
use Sales\Form\ShipOneOrderForm;
use Sales\Form\ShipOrderForm;
use Sales\Service\OrderChangeAmountManager;
use Sales\Service\OrderDeliveryAddressManager;
use Sales\Service\OrderDiscountRecordManager;
use Sales\Service\OrderGoodsManager;
use Sales\Service\OrderManager;
use Sales\Service\OrderSelfLocationManager;
use Sales\Service\OrderStatusManager;
use User\Entity\User;
use User\Entity\UserIntegralConfirm;
use User\Service\BalanceLogManager;
use User\Service\UserIntegralConfirmManager;
use User\Service\UserManager;

class IndexController extends AdminActionController
{
    private $translator;
    private $entityManager;
    private $orderManager;
    private $orderChangeAmountManager;
    private $orderDeliveryAddressManager;
    private $orderGoodsManager;
    private $orderSelfLocationManager;
    private $orderStatusManager;
    private $userIntegralConfirmManager;
    private $orderDiscountRecordManager;
    private $userCouponManager;
    private $userManager;
    private $balanceLogManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        OrderManager    $orderManager,
        OrderChangeAmountManager    $orderChangeAmountManager,
        OrderDeliveryAddressManager $orderDeliveryAddressManager,
        OrderGoodsManager           $orderGoodsManager,
        OrderSelfLocationManager    $orderSelfLocationManager,
        OrderStatusManager          $orderStatusManager,
        UserIntegralConfirmManager  $userIntegralConfirmManager,
        OrderDiscountRecordManager  $orderDiscountRecordManager,
        UserCouponManager           $userCouponManager,
        UserManager     $userManager,
        BalanceLogManager           $balanceLogManager
    )
    {
        $this->translator       = $translator;
        $this->entityManager    = $entityManager;
        $this->orderManager     = $orderManager;
        $this->orderChangeAmountManager     = $orderChangeAmountManager;
        $this->orderDeliveryAddressManager  = $orderDeliveryAddressManager;
        $this->orderGoodsManager= $orderGoodsManager;
        $this->orderSelfLocationManager     = $orderSelfLocationManager;
        $this->orderStatusManager= $orderStatusManager;
        $this->userIntegralConfirmManager   = $userIntegralConfirmManager;
        $this->orderDiscountRecordManager   = $orderDiscountRecordManager;
        $this->userCouponManager= $userCouponManager;
        $this->userManager      = $userManager;
        $this->balanceLogManager= $balanceLogManager;
    }

    /**
     * 订单列表
     * @return array|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $page = (int) $this->params()->fromQuery('page', 1);

        $search = [];
        $searchForm = new SearchOrderForm();
        $searchForm->get('order_status')->setValueOptions(Common::orderStatus($this->translator));
        $searchForm->get('delivery_type')->setValueOptions(Common::deliveryArray($this->translator));
        if($this->getRequest()->isGet()) {
            $data = $this->params()->fromQuery();
            $searchForm->setData($data);
            if($searchForm->isValid()) $search = $searchForm->getData();
        }

        $query      = $this->entityManager->getRepository(Order::class)->findOrderList($search);
        $paginator  = $this->adminCommon()->shopPaginator($query, $page);

        //动态绑定的快递id数组
        $deliveryIdArray = $this->shopPlugin()->getExpressCodeIdArray();

        return ['orderList' => $paginator, 'deliveryIdArray' => $deliveryIdArray, 'searchForm' => $searchForm];
    }

    /**
     * 订单详情
     * @return array|\Laminas\Http\Response
     */
    public function detailAction()
    {
        $orderId = (int) $this->params()->fromRoute('id', -1);
        $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if($orderInfo == null) {
            //$this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不存在!'));
            return $this->redirect()->toRoute('sales');
        }

        $queryData = $this->params()->fromQuery();

        $orderSelfLocation = null;
        if ($orderInfo->getDeliveryType() == 'selfFetch') $orderSelfLocation = $this->entityManager->getRepository(OrderSelfLocation::class)->findOneBy(['orderId' => $orderId]);

        $deliveryAddress = null;
        if ($orderInfo->getDeliveryType() == 'delivery') $deliveryAddress = $this->entityManager->getRepository(OrderDeliveryAddress::class)->findOneBy(['orderId' => $orderId]);

        //可获取积分
        $integral = $this->entityManager->getRepository(UserIntegralConfirm::class)->findOneBy(['id' => $orderInfo->getOrderId(), 'confirmType' => 'order']);

        //订单优惠记录
        $orderDiscountRecord = $this->entityManager->getRepository(OrderDiscountRecord::class)->findBy(['orderId' => $orderId]);

        //订单操作历史
        $orderStatusLog = $this->entityManager->getRepository(OrderStatus::class)->findBy(['orderId' => $orderId]);

        //订单金额修改历史
        $orderChangeAmountLog = $this->entityManager->getRepository(OrderChangeAmount::class)->findBy(['orderId' => $orderId]);

        //动态绑定的快递id数组
        $deliveryIdArray = $this->shopPlugin()->getExpressCodeIdArray();

        return [
            'queryData'         => $queryData,
            'orderInfo'         => $orderInfo,
            'orderSelfLocation' => $orderSelfLocation,
            'deliveryAddress'   => $deliveryAddress,
            'orderStatusLog'    => $orderStatusLog,
            'integral'          => $integral,
            'orderChangeAmountLog'  => $orderChangeAmountLog,
            'orderDiscountRecord'   => $orderDiscountRecord,
            'deliveryIdArray'   => $deliveryIdArray
        ];
    }

    /**
     * 订单金额修改操作
     * @return array|\Laminas\Http\Response
     */
    public function changeOrderAmountAction()
    {
        $orderId = (int) $this->params()->fromRoute('id', -1);
        $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if($orderInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不存在!'));
            return $this->adminCommon()->toReferer();
        }
        if($orderInfo->getOrderStatus() >= Common::ORDER_GOODS_SHIPPED || $orderInfo->getPaymentFinishTime()) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单价格不可修改!'));
            return $this->adminCommon()->toReferer();
        }

        $queryData = $this->params()->fromQuery();

        $form = new ChangeOrderAmountForm();
        $form->get('orderChangeType')->setValueOptions(Common::changeType($this->translator));
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                if($data['orderChangeType'] == '-' && $data['orderChangeNum'] > $orderInfo->getOrderAmount()) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('修改金额超过限制金额!'));
                    return $this->adminCommon()->toReferer();
                }
                $this->entityManager->beginTransaction();
                try {
                    $orderChangeNum     = $data['orderChangeType'].$data['orderChangeNum'];
                    $orderChangeInfo    = $this->orderChangeAmountManager->addOrderChangeAmount(
                        [
                            'orderAmount'           => $orderInfo->getOrderAmount(),
                            'orderOriginalAmount'   => $orderInfo->getOrderAmount() + $orderChangeNum,
                            'orderChangeType'       => $data['orderChangeType'],
                            'orderChangeNum'        => $data['orderChangeNum'],
                            'orderChangeTime'       => time(),
                            'operateUser'           => $this->adminCommon()->admin('admin_name'),
                            'orderChangeInfo'       => $data['orderChangeInfo'],
                            'orderId'               => $orderId
                        ]
                    );

                    $orderCurrencyRate  = Common::configValue($orderInfo->getCurrencyCode(), 'currency')['rate'];
                    $baseOrderAmount    = number_format($orderChangeInfo->getOrderOriginalAmount()/$orderCurrencyRate, 2, '.', '');

                    $this->orderManager->editOrder(['orderAmount' => $orderChangeInfo->getOrderOriginalAmount(), 'baseOrderAmount' => $baseOrderAmount], $orderInfo);
                    $this->getEventManager()->trigger('backstage-order.editOrderAmount.post', $this, ['order' => $orderInfo]);
                    $this->entityManager->commit();
                    $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 金额修改成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                } catch (\Exception $e) {
                    $this->entityManager->rollback();
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('订单金额修改失败!'));
                }
                return $this->redirect()->toRoute('sales', ['action' => 'detail', 'id' => $orderId], ['query' => $queryData]);
            }
        }

        return ['orderInfo' => $orderInfo, 'form' => $form, 'queryData' => $queryData];
    }

    /**
     * 订单付款处理
     * @return array|\Laminas\Http\Response
     */
    public function payOrderAction()
    {
        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if(
            $orderInfo == null
            || $orderInfo->getOrderStatus() > $this->salesPlugin()->getOrderStatusCode('wait_payment')
            || $orderInfo->getPaymentType() == 'CashOnDelivery'
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能进行付款处理!'));
            return $this->adminCommon()->toReferer();
        }

        /*if($orderInfo->getPaymentType() == 'OnlinePay' && empty($orderInfo->getPaymentCode())) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('在线支付，必须客户选择了支付方式后，管理员才能在后台进行支付处理!'));
            return $this->adminCommon()->toReferer();
        }*/

        $queryData = $this->params()->fromQuery();

        $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userId' => $orderInfo->getUserId()]);
        $form = new PayOrderForm($userInfo->getUserMoney(), $orderInfo->getBaseOrderAmount());
        $form->get('paymentCode')->setValueOptions($this->adminCommon()->paymentList('true', true));
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $paymentConfig = Common::getPaymentConfig($data['paymentCode']);

                $this->entityManager->beginTransaction();
                try {
                    if ($data['paymentCode'] == 'BalancePay') {//如果是余额支付，则进行余额处理
                        $userMoney = $userInfo->getUserMoney() - $orderInfo->getBaseOrderAmount();
                        $this->balanceLogManager->addBalanceLog([
                            'userId'            => $userInfo->getUserId(),
                            'userName'          => $userInfo->getUserName(),
                            'adminId'           => $this->adminCommon()->admin('admin_id'),
                            'adminName'         => $this->adminCommon()->admin('admin_name'),
                            'balanceChangeType' => 4,//订单支付
                            'balanceChangeNum'  => '-'.$orderInfo->getBaseOrderAmount(),
                            'balanceChangedAmount' => $userMoney,
                            'balanceChangeTime' => time(),
                            'balanceChangeInfo' => $this->translator->translate('订单编号').'：'.$orderInfo->getOrderSn()
                        ]);
                        $this->userManager->updateUserMoney($userMoney, $userInfo);
                    }

                    $orderInfo = $this->orderManager->editOrder(['paymentCode' => $data['paymentCode'], 'paymentName' => $paymentConfig['paymentName']['content'], 'orderStatus' => $this->salesPlugin()->getOrderStatusCode('FINISH_PAYMENT'), 'paymentFinishTime' => time()], $orderInfo);
                    $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => $this->translator->translate('管理员'), 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $data['statusInfo'], 'statusTime' => $orderInfo->getPaymentFinishTime()]);
                    $this->getEventManager()->trigger('backstage-order.pay.post', $this, ['orderInfo' => $orderInfo]);

                    $this->entityManager->commit();
                    $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 付款成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                } catch (\Exception $e) {
                    $this->entityManager->rollback();
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('订单付款失败!'));
                }
                if(isset($queryData['return']) && $queryData['return'] == 'detail') return $this->redirect()->toRoute('sales', ['action' => 'detail', 'id' => $orderInfo->getOrderId()]);
                else return $this->redirect()->toRoute('sales', [], ['query' => $queryData]);
            }
        }

        if (!empty($orderInfo->getPaymentCode())) $form->setData(['paymentCode' => $orderInfo->getPaymentCode()]);

        return ['form' => $form, 'orderInfo' => $orderInfo, 'queryData' => $queryData];
    }

    /**
     * 订单发货处理
     * @return array|\Laminas\Http\Response|ViewModel
     */
    public function shipOrderAction()
    {
        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if(
            $orderInfo == null
            || $orderInfo->getOrderStatus() > $this->salesPlugin()->getOrderStatusCode('FINISH_DISTRIBUTION_GOODS')
            || $orderInfo->getOrderStatus() < $this->salesPlugin()->getOrderStatusCode('wait_payment')
            || $orderInfo->getDeliveryType() != 'delivery'
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能进行发货处理!'));
            return $this->adminCommon()->toReferer();
        }

        //判断是否有虚拟商品，库存是否需要补货
        $orderGoodsVirtual  = $this->entityManager->getRepository(OrderGoods::class)->findBy(['orderId' => $orderId, 'goodsType' => 2]);
        $vGoodsStockFew     = [];
        if ($orderGoodsVirtual) foreach ($orderGoodsVirtual as $goodsValue) {
            $virtualGoodsInfo = $this->entityManager->getRepository(GoodsVirtual::class)->findOneBy(['goodsId' => $goodsValue->getGoodsId(), 'virtualGoodsState' => 1]);
            if (($virtualGoodsInfo && $virtualGoodsInfo->getVirtualGoodsAccountType() == 1 && $virtualGoodsInfo->getVirtualGoodsPasswordType() == 1) || $virtualGoodsInfo == null) {
                //可用的虚拟商品数量
                $vGoodsNum1 = $this->entityManager->getRepository(GoodsVirtual::class)->findGoodsVirtualCount(['goodsId' => $goodsValue->getGoodsId(), 'virtualGoodsState' => 1]);
                //已经在该订单使用的虚拟商品数量
                $vGoodsNum2 = $this->entityManager->getRepository(GoodsVirtual::class)->findGoodsVirtualCount(['goodsId' => $goodsValue->getGoodsId(), 'virtualGoodsState' => 2, 'orderId' => $goodsValue->getOrderId()]);
                $buyVirtualNum = $goodsValue->getBuyNum() - $vGoodsNum2;
                if ($buyVirtualNum > $vGoodsNum1) $vGoodsStockFew[$goodsValue->getGoodsId()] = ['num' => $buyVirtualNum - $vGoodsNum1];
            }
        }

        $queryData = $this->params()->fromQuery();

        if(isset($queryData['mode']) && $queryData['mode'] == 2) {
            $form = new ShipOneOrderForm($orderId, $this->entityManager);
        } else {
            $form = new ShipOrderForm();
            $form->get('deliveryId')->setValueOptions($this->adminCommon()->deliveryNameOptions());
        }
        $form->get('deliveryMode')->setValueOptions(Common::deliveryMode($this->translator));
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                if (!empty($vGoodsStockFew)) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('请将商品库存补全后，在进行发货处理!'));
                    return $this->adminCommon()->toReferer();
                }

                $data = $form->getData();

                if(isset($queryData['mode']) && $queryData['mode'] == 2) {//单独配送
                    $this->entityManager->beginTransaction();
                    try {
                        $orderInfo = $this->orderManager->editOrder(
                            [
                                'orderStatus'   => $this->salesPlugin()->getOrderStatusCode('GOODS_SHIPPED'),
                                'deliveryMode'  => 2,
                                'expressTime'   => time()
                            ], $orderInfo);
                        $this->orderGoodsManager->changeOrderGoodsShip($data, $orderInfo->getOrderStatus(), $orderId, $this->adminCommon()->deliveryNameOptions());
                        $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => $this->translator->translate('管理员'), 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $data['statusInfo'], 'statusTime' => $orderInfo->getExpressTime()]);
                        $this->getEventManager()->trigger('backstage-order.ship.post', $this, ['orderInfo' => $orderInfo]);

                        $this->entityManager->commit();
                        $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 发货成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                    } catch (\Exception $e) {
                        $this->entityManager->rollback();
                        $this->flashMessenger()->addWarningMessage($this->translator->translate('订单发货失败!'));
                    }
                } else {//统一配送
                    $deliveryInfo = $this->entityManager->getRepository(Delivery::class)->findOneBy(['deliveryId' => $data['deliveryId']]);
                    $this->entityManager->beginTransaction();
                    try {
                        $orderInfo = $this->orderManager->editOrder(
                            [
                                'orderStatus'   => $this->salesPlugin()->getOrderStatusCode('GOODS_SHIPPED'),
                                'deliveryMode'  => 1,
                                'deliveryId'    => $data['deliveryId'],
                                'deliveryName'  => $deliveryInfo->getDeliveryName(),
                                'expressNumber' => $data['expressNumber'],
                                'expressTime'   => time()
                            ], $orderInfo);
                        $this->orderGoodsManager->changeOrderGoodsStatus($orderInfo->getOrderStatus(), $orderId);
                        $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => $this->translator->translate('管理员'), 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $data['statusInfo'], 'statusTime' => $orderInfo->getExpressTime()]);
                        $this->getEventManager()->trigger('backstage-order.ship.post', $this, ['orderInfo' => $orderInfo]);

                        $this->entityManager->commit();
                        $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 发货成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                    } catch (\Exception $e) {
                        $this->entityManager->rollback();
                        $this->flashMessenger()->addWarningMessage($this->translator->translate('订单发货失败!'));
                    }
                }

                if(isset($queryData['return']) && $queryData['return'] == 'detail') return $this->redirect()->toRoute('sales', ['action' => 'detail', 'id' => $orderInfo->getOrderId()]);
                else return $this->redirect()->toRoute('sales', [], ['query' => $queryData]);
            }
        }

        $orderDeliveryAddress = $this->entityManager->getRepository(OrderDeliveryAddress::class)->findOneBy(['orderId' => $orderId]);

        $array = ['orderInfo' => $orderInfo, 'vGoodsStockFew' => $vGoodsStockFew, 'form' => $form, 'orderDeliveryAddress' => $orderDeliveryAddress, 'queryData' => $queryData];

        $view = new ViewModel();
        if(isset($queryData['mode']) && $queryData['mode'] == 2) {
            $array['deliveryArray'] = $this->adminCommon()->deliveryNameOptions();
            $view->setTemplate('sales/index/ship-one-order');
            return $view->setVariables($array);
        }

        return $array;
    }

    /**
     * 虚拟商品发货
     * @return array|\Laminas\Http\Response
     */
    public function sendOrderGoodsVirtualAction()
    {
        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'deliveryType' => 'autoDelivery']);
        if(
            $orderInfo == null
            || $orderInfo->getOrderStatus() > $this->salesPlugin()->getOrderStatusCode('FINISH_DISTRIBUTION_GOODS')
            || $orderInfo->getOrderStatus() < $this->salesPlugin()->getOrderStatusCode('wait_payment')
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能进行发货处理!'));
            return $this->adminCommon()->toReferer();
        }

        //判断虚拟商品是否需要补货
        $orderGoods     = $orderInfo->getOrderGoods();
        $vGoodsStockFew = [];
        foreach ($orderGoods as $goodsValue) {
            $virtualGoodsInfo = $this->entityManager->getRepository(GoodsVirtual::class)->findOneBy(['goodsId' => $goodsValue->getGoodsId(), 'virtualGoodsState' => 1]);
            if (($virtualGoodsInfo && $virtualGoodsInfo->getVirtualGoodsAccountType() == 1 && $virtualGoodsInfo->getVirtualGoodsPasswordType() == 1) || $virtualGoodsInfo == null) {
                //可用的虚拟商品数量
                $vGoodsNum1 = $this->entityManager->getRepository(GoodsVirtual::class)->findGoodsVirtualCount(['goodsId' => $goodsValue->getGoodsId(), 'virtualGoodsState' => 1]);
                //已经在该订单使用的虚拟商品数量
                $vGoodsNum2 = $this->entityManager->getRepository(GoodsVirtual::class)->findGoodsVirtualCount(['goodsId' => $goodsValue->getGoodsId(), 'virtualGoodsState' => 2, 'orderId' => $goodsValue->getOrderId()]);
                $buyVirtualNum = $goodsValue->getBuyNum() - $vGoodsNum2;
                if ($buyVirtualNum > $vGoodsNum1) $vGoodsStockFew[$goodsValue->getGoodsId()] = ['num' => $buyVirtualNum - $vGoodsNum1];
            }
        }

        $queryData = $this->params()->fromQuery();

        $form = new SendOrderGoodsVirtualForm();
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                if (!empty($vGoodsStockFew)) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('请将商品库存补全后，在进行发货处理!'));
                    return $this->redirect()->toRoute('sales', ['action' => 'sendOrderGoodsVirtual', 'id' => $orderId], ['query' => $queryData]);
                }

                $data = $form->getData();
                $this->entityManager->beginTransaction();
                try {
                    $orderInfo = $this->orderManager->editOrder(
                        [
                            'orderStatus'   => $this->salesPlugin()->getOrderStatusCode('GOODS_SHIPPED'),
                            'deliveryMode'  => 1,
                            'expressTime'   => time()
                        ], $orderInfo);
                    $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => $this->translator->translate('管理员'), 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $data['statusInfo'], 'statusTime' => $orderInfo->getExpressTime()]);
                    $this->getEventManager()->trigger('backstage-order.ship.post', $this, ['orderInfo' => $orderInfo]);

                    $this->entityManager->commit();
                    $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 发货成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                } catch (\Exception $e) {
                    $this->entityManager->rollback();
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('订单发货失败!'));
                }

                return $this->redirect()->toRoute('sales', [], ['query' => $queryData]);
            }
        }

        return ['orderInfo' => $orderInfo, 'vGoodsStockFew' => $vGoodsStockFew, 'orderGoods' => $orderGoods, 'form' => $form, 'queryData' => $queryData];
    }

    /**
     * 物流轨迹查看
     * @return array[]|mixed
     */
    public function showOrderExpressTrackAction()
    {
        if (Common::configValue('deliveryApiState', 'delivery') != 1) return $this->response->setContent($this->translator->translate('物流轨迹已经关闭，无法查看'));

        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if($orderInfo == null) return $this->adminCommon()->toReferer();

        $queryData = $this->params()->fromQuery();

        $expressContent = null;
        if ($orderInfo->getDeliveryMode() == 1) {//统一模式
            if (!empty($orderInfo->getExpressNumber())) {
                $deliveryInfo = $this->entityManager->getRepository(Delivery::class)->findOneBy(['deliveryId' => $orderInfo->getDeliveryId()]);
                if (!empty($deliveryInfo->getDeliveryNameCode())) $expressContent = ExpressApi::expressQuery($deliveryInfo->getDeliveryNameCode(), $orderInfo->getExpressNumber());
            }
        } elseif ($orderInfo->getDeliveryMode() == 2) {//单独配送模式
            $deliveryIdArray = $this->shopPlugin()->getExpressCodeIdArray();
            foreach ($orderInfo->getOrderGoods() as $key => $goodsValue) {
                $expressContent['goods'][$key] = [
                    'goodsName'     => $goodsValue->getGoodsName(),
                    'deliveryName'  => $goodsValue->getDeliveryName(),
                    'expressNumber' => $goodsValue->getExpressNumber()
                ];
                if ($goodsValue->getGoodsType() == 1 && $goodsValue->getDeliveryId() > 0 && isset($deliveryIdArray[$goodsValue->getDeliveryId()])) {
                    $expressContent['goods'][$key]['expressContent'] = ExpressApi::expressQuery($deliveryIdArray[$goodsValue->getDeliveryId()], $goodsValue->getExpressNumber());
                }
            }
        }

        return ['orderInfo' => $orderInfo, 'expressContent' => $expressContent, 'queryData' => $queryData];
    }

    /**
     * 修改订单快递单号
     * @return array|\Laminas\Http\Response|ViewModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function editOrderExpressNumberAction()
    {
        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'deliveryType' => 'delivery']);
        if(
            $orderInfo == null
            || $orderInfo->getOrderStatus() < $this->salesPlugin()->getOrderStatusCode('GOODS_SHIPPED')
            || $orderInfo->getOrderStatus() >= $this->salesPlugin()->getOrderStatusCode('GOODS_RECEIVED')
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能进行修改快递单号的操作!'));
            return $this->adminCommon()->toReferer();
        }

        if($orderInfo->getDeliveryMode() == 2) {
            $form = new EditOneOrderExpressNumberForm($orderId, $this->entityManager);
        } else {
            $form = new EditOrderExpressNumberForm();
        }

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                if($orderInfo->getDeliveryMode() == 2) {
                    $this->orderGoodsManager->changeOrderGoodsExpressNumber($data, $orderId);
                } else {
                    $this->orderManager->editOrder(['expressNumber' => $data['expressNumber']], $orderInfo);
                }

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 快递单号修改成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                return $this->redirect()->toRoute('sales', ['action' => 'editOrderExpressNumber', 'id' => $orderInfo->getOrderId()]);
            }
        }
        $form->setData(['expressNumber' => $orderInfo->getExpressNumber()]);

        $orderStatusInfo = $this->entityManager->getRepository(OrderStatus::class)->findOneBy(['orderId' => $orderId, 'orderStatus' => $this->salesPlugin()->getOrderStatusCode('GOODS_SHIPPED')]);

        $array = ['form' => $form, 'orderInfo' => $orderInfo, 'orderStatusInfo' => $orderStatusInfo];

        $view = new ViewModel();
        if($orderInfo->getDeliveryMode() == 2) {
            $view->setTemplate('sales/index/edit-one-order-express-number');
            return $view->setVariables($array);
        }

        return $array;
    }

    /**
     * 订单收货
     * @return array|\Laminas\Http\Response
     */
    public function receiptOrderAction()
    {
        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if(
            $orderInfo == null
            || (
                $orderInfo->getDeliveryType() !='selfFetch'
                && ($orderInfo->getOrderStatus() < $this->salesPlugin()->getOrderStatusCode('GOODS_SHIPPED') || $orderInfo->getOrderStatus() >= $this->salesPlugin()->getOrderStatusCode('GOODS_RECEIVED'))
            )
            || (
                $orderInfo->getDeliveryType() =='selfFetch'
                && ($orderInfo->getOrderStatus() < $this->salesPlugin()->getOrderStatusCode('WAIT_GOODS_ARRIVE') || $orderInfo->getOrderStatus() >= $this->salesPlugin()->getOrderStatusCode('GOODS_RECEIVED'))
            )
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能进行收货处理!'));
            return $this->adminCommon()->toReferer();
        }

        $queryData = $this->params()->fromQuery();

        $form = new ReceiptOrderForm();
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                $this->entityManager->beginTransaction();
                try {
                    $orderInfo = $this->orderManager->editOrder(['orderStatus' => $this->salesPlugin()->getOrderStatusCode('GOODS_RECEIVED'), 'orderFinishTime' => time()], $orderInfo);
                    $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => $this->translator->translate('管理员'), 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $data['statusInfo'], 'statusTime' => $orderInfo->getOrderFinishTime()]);
                    $this->getEventManager()->trigger('backstage-order.receipt.post', $this, ['orderInfo' => $orderInfo]);

                    $this->entityManager->commit();
                    $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 收货完成!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                } catch (\Exception $e) {
                    $this->entityManager->rollback();
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('订单收货失败!'));
                }
                if(isset($queryData['return']) && $queryData['return'] == 'detail') return $this->redirect()->toRoute('sales', ['action' => 'detail', 'id' => $orderInfo->getOrderId()]);
                else return $this->redirect()->toRoute('sales', [], ['query' => $queryData]);
            }
        }

        return ['orderInfo' => $orderInfo, 'form' => $form, 'queryData' => $queryData];
    }

    /**
     * 取消订单
     * @return array|\Laminas\Http\Response
     */
    public function cancelOrderAction()
    {
        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if(
            $orderInfo == null
            || ($orderInfo->getPaymentType() == 'OnlinePay' && $orderInfo->getOrderStatus() >= $this->salesPlugin()->getOrderStatusCode('WAIT_GOODS_ARRIVE'))
            || ($orderInfo->getPaymentType() == 'CashOnDelivery' && $orderInfo->getOrderStatus() >= $this->salesPlugin()->getOrderStatusCode('salesPlugin'))
            || $orderInfo->getOrderStatus() == $this->salesPlugin()->getOrderStatusCode('CANCEL_ORDER')
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能取消!'));
            return $this->adminCommon()->toReferer();
        }

        $queryData = $this->params()->fromQuery();

        $form = new CancelOrderForm();
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                $this->entityManager->beginTransaction();
                try {
                    $orderInfo = $this->orderManager->editOrder(['orderStatus' => $this->salesPlugin()->getOrderStatusCode('cancel_order')], $orderInfo);
                    $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => $this->translator->translate('管理员'), 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $data['statusInfo'], 'statusTime' => time()]);
                    $this->getEventManager()->trigger('backstage-order.cancel.post', $this, ['orderInfo' => $orderInfo, 'admin_id' => $this->adminCommon()->admin('admin_id'), 'admin_name' => $this->adminCommon()->admin('admin_name')]);
                    $this->entityManager->commit();
                    $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 取消成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
                } catch (\Exception $e) {
                    $this->entityManager->rollback();
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('订单取消失败!'));
                }
                if(isset($queryData['return']) && $queryData['return'] == 'detail') return $this->redirect()->toRoute('sales', ['action' => 'detail', 'id' => $orderInfo->getOrderId()]);
                else return $this->redirect()->toRoute('sales', [], ['query' => $queryData]);
            }
        }

        return ['orderInfo' => $orderInfo, 'queryData' => $queryData, 'form' => $form];
    }

    /**
     * 订单打印
     * @return array
     */
    public function printOrderAction()
    {
        $orderId = (int) $this->params()->fromRoute('id', -1);
        $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId]);
        if($orderInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不存在!'));
            return $this->adminCommon()->toReferer();
        }

        $queryData = $this->params()->fromQuery();

        $orderSelfLocation = null;
        if ($orderInfo->getDeliveryType() == 'selfFetch') $orderSelfLocation = $this->entityManager->getRepository(OrderSelfLocation::class)->findOneBy(['orderId' => $orderId]);

        $deliveryAddress = null;
        if ($orderInfo->getDeliveryType() == 'delivery') $deliveryAddress = $this->entityManager->getRepository(OrderDeliveryAddress::class)->findOneBy(['orderId' => $orderId]);

        //订单优惠记录
        $orderDiscountRecord = $this->entityManager->getRepository(OrderDiscountRecord::class)->findBy(['orderId' => $orderId]);

        //订单金额修改历史
        $orderChangeAmountLog = $this->entityManager->getRepository(OrderChangeAmount::class)->findBy(['orderId' => $orderId]);

        return [
            'queryData'         => $queryData,
            'orderInfo'         => $orderInfo,
            'orderSelfLocation' => $orderSelfLocation,
            'deliveryAddress'   => $deliveryAddress,
            'orderDiscountRecord'   => $orderDiscountRecord,
            'orderChangeAmountLog'  => $orderChangeAmountLog
        ];
    }

    /**
     * 删除订单
     * @return mixed
     */
    public function deleteAction()
    {
        if(!$this->adminCommon()->validatorCsrf()) return $this->adminCommon()->toReferer();

        $orderId = (int) $this->params()->fromRoute('id', -1);
        $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'orderStatus' => Common::orderStatusCode('CANCEL_ORDER')]);
        if($orderInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不存在或者该订单状态不允许删除!'));
            return $this->adminCommon()->toReferer();
        }

        $this->entityManager->beginTransaction();
        try {
            $this->orderManager->deleteOrder($orderInfo);
            $this->orderChangeAmountManager->deleteOrderChangeAmount($orderId);
            $this->orderDeliveryAddressManager->deleteOrderDeliveryAddress($orderId);
            $this->orderGoodsManager->deleteOrderGoods($orderId);
            $this->orderSelfLocationManager->deleteOrderSelfLocation($orderId);
            $this->orderStatusManager->deleteOrderStatus($orderId);
            $this->userIntegralConfirmManager->deleteUserIntegralConfirm($orderId, 'order');
            $this->userCouponManager->deleteUserOrderCoupon($orderId);
            $this->orderDiscountRecordManager->deleteOrderDiscountRecord($orderId);
            $this->entityManager->commit();
            $this->adminCommon()->addOperLog(sprintf($this->translator->translate('订单 %s 删除成功!'), $orderInfo->getOrderSn()), $this->translator->translate('订单管理'));
        } catch (\Exception $e) {
            $this->entityManager->rollback();
            $this->flashMessenger()->addWarningMessage($this->translator->translate('订单删除失败!'));
        }
        return $this->adminCommon()->toReferer();
    }

    /**
     * 支付记录列表
     * @return array
     */
    public function orderPaymentLogAction()
    {
        $page = (int) $this->params()->fromQuery('page', 1);

        $search = [];
        $searchForm = new SearchOrderPaymentLogForm();
        $searchForm->get('payment_code')->setValueOptions($this->adminCommon()->paymentList());
        $searchForm->get('payment_state')->setValueOptions([1 => $this->translator->translate('已支付'), 2 => $this->translator->translate('未支付')]);
        if($this->getRequest()->isGet()) {
            $data = $this->params()->fromQuery();
            $searchForm->setData($data);
            if($searchForm->isValid()) $search = $searchForm->getData();
        }

        $query      = $this->entityManager->getRepository(Order::class)->findOrderPaymentLog($search);
        $paginator  = $this->adminCommon()->shopPaginator($query, $page);

        return ['paymentLogList' => $paginator, 'searchForm' => $searchForm];
    }
}